#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "../inc/data.h"
#include "general.h"
#include "../inc/flight_node.h"
#include "../inc/my_flight_node.h"

flight_Node_p flight_Init()
{

    flight_Node_p headNode = flight_create();
    if (!headNode)
        return NULL;

    // 初始化空链表：头节点自循环
    headNode->next = headNode;
    headNode->prev = headNode;

    flight_t flight[] = {
        // 格式：航空公司,航班号,起飞地,目的地,日期,时间,票价[5种],燃油费,机场建设费,座位数[5种],剩余座位数[5种]                  商务舱，一等舱，经济舱，头等舱，公务舱
        {"中国国航", "CA1519", "上海", "北京", "2025-09-05", "12:00", {3200, 2700, 1300, 3800, 3000}, {25, 35, 160, 12, 18}, {23, 32, 156, 10, 16}, 0},
        {"中国国航", "CA1501", "北京", "上海", "2025-09-01", "08:00", {3200, 2700, 1300, 3800, 3000}, {25, 35, 160, 12, 18}, {23, 32, 156, 10, 16}, 0},
        {"东方航空", "MU5101", "上海", "北京", "2025-07-01", "09:30", {3000, 2500, 1200, 3500, 2800}, {20, 30, 150, 10, 15}, {18, 30, 150, 10, 14}, 1},
        {"南方航空", "CZ3101", "广州", "北京", "2025-05-02", "10:15", {3500, 3000, 1500, 4000, 3200}, {30, 40, 170, 15, 20}, {30, 40, 169, 13, 20}, 1},
        {"中国国航", "CA1837", "北京", "广州", "2025-06-02", "11:45", {3400, 2900, 1400, 3900, 3100}, {28, 38, 165, 14, 19}, {28, 38, 165, 14, 19}, 1},
        {"东方航空", "MU5301", "上海", "广州", "2025-05-03", "13:20", {3100, 2600, 1250, 3600, 2900}, {24, 32, 155, 12, 16}, {24, 32, 155, 12, 16}, 0},
        {"南方航空", "CZ3602", "深圳", "成都", "2025-05-03", "14:30", {2800, 2300, 1100, 3300, 2600}, {22, 30, 145, 11, 15}, {22, 30, 145, 11, 15}, 0},
        {"中国国航", "CA1321", "北京", "成都", "2025-05-24", "15:45", {3300, 2800, 1350, 3800, 3000}, {26, 36, 160, 13, 17}, {26, 36, 160, 13, 17}, 1},
        {"东方航空", "MU2468", "上海", "西安", "2025-05-04", "16:50", {2900, 2400, 1150, 3400, 2700}, {21, 29, 140, 10, 14}, {21, 29, 140, 10, 14}, 0},
        {"南方航空", "CZ6891", "广州", "重庆", "2025-05-05", "17:30", {3000, 2500, 1200, 3500, 2800}, {23, 31, 150, 11, 15}, {23, 31, 150, 11, 15}, 0},
        {"中国国航", "CA4523", "成都", "昆明", "2025-05-05", "18:15", {2600, 2100, 1000, 3100, 2400}, {18, 25, 130, 8, 12}, {18, 25, 130, 8, 12}, 1},
        {"东方航空", "MU3579", "杭州", "厦门", "2025-05-06", "19:00", {2500, 2000, 950, 3000, 2300}, {17, 24, 125, 9, 13}, {17, 24, 125, 9, 13}, 0},
        {"南方航空", "CZ4721", "武汉", "长沙", "2025-05-06", "20:20", {2300, 1800, 850, 2800, 2100}, {15, 22, 120, 7, 11}, {15, 22, 120, 7, 11}, 0},
        {"中国国航", "CA6789", "西安", "乌鲁木齐", "2025-04-07", "21:10", {3500, 3000, 1500, 4000, 3200}, {30, 40, 170, 15, 20}, {30, 40, 170, 15, 20}, 1},
        {"东方航空", "MU8642", "南京", "青岛", "2025-05-07", "22:05", {2400, 1900, 900, 2900, 2200}, {16, 23, 130, 8, 12}, {16, 23, 130, 8, 12}, 0},
        {"南方航空", "CZ9513", "沈阳", "哈尔滨", "2025-05-08", "23:00", {2200, 1700, 800, 2700, 2000}, {14, 20, 110, 6, 10}, {14, 20, 110, 6, 10}, 0}};

    int length = sizeof(flight) / sizeof(flight[0]);

    for (int i = 0; i < length; i++)
    {
        flight_Node_p node = flight_create();
        if (!node)
            continue;

        // 填充数据
        node->data = malloc(sizeof(flight_t));
        if (!node->data)
        {
            free(node);
            continue;
        }

        // 复制航班数据到节点
        memcpy(node->data, &flight[i], sizeof(flight_t));

        // 将新节点插入到链表尾部
        flight_Node_p tail = headNode->prev; // 当前尾节点

        tail->next = node;
        node->prev = tail;

        node->next = headNode; // 新节点指向头节点（循环）
        headNode->prev = node; // 头节点指向新尾节点
    }

    return headNode;
}

flight_Node_p flightByAirline_Init(flight_Node_p headNode, char *airline)
{

    flight_Node_p airlineHead = flight_create();
    if (!airlineHead)
        return NULL;

    flight_Node_p currNode = headNode->next;
    flight_Node_p tailNode = airlineHead;

    while (currNode != headNode)
    {
        if (strcmp(currNode->data->airline, airline) == 0)
        {

            flight_Node_p newNode = flight_create();
            if (!newNode)
                continue;

            newNode->data = malloc(sizeof(flight_t));
            if (!newNode->data)
            {
                free(newNode);
                continue;
            }
            memcpy(newNode->data, currNode->data, sizeof(flight_t));

            // 插入到新链表尾部
            tailNode->next = newNode;
            newNode->prev = tailNode;
            newNode->next = airlineHead;
            airlineHead->prev = newNode;
            tailNode = newNode; // 更新尾节点
        }
        currNode = currNode->next;
    }

    return airlineHead;
}

flight_Node_p flight_create()
{
    flight_Node_p currNode = (flight_Node_p)malloc(sizeof(flight_Node_t));
    currNode->data = NULL;
    currNode->next = currNode;
    currNode->prev = currNode;
    return currNode;
}

// 头插
void flight_insert(flight_Node_p headNode, flight_p flight)
{
    if (!headNode)
    {
        return;
    }

    flight_Node_p newNode = flight_create();
    newNode->data = flight;
    if (!newNode)
    {
        return;
    }

    newNode->next = headNode->next;
    headNode->next->prev = newNode;
    headNode->next = newNode;
    newNode->prev = headNode;
}

// 尾插
void flight_insert_tail(flight_Node_p headNode, flight_p flight)
{
    if (!headNode)
    {
        return;
    }

    flight_Node_p newNode = flight_create();
    newNode->data = flight;
    if (!newNode)
    {
        return;
    }

    headNode->prev->next = newNode;
    newNode->prev = headNode->prev;
    newNode->next = headNode;
    headNode->prev = newNode;
}

// 获取座位类型
char *flight_index_to_type(int index)
{
    switch (index)
    {
    case 0:
        return "商务舱";
    case 1:
        return "一等舱";
    case 2:
        return "经济舱";
    case 3:
        return "头等舱";
    case 4:
        return "公务舱";
    }
}

int seatOrRemainder_num(flight_Node_p currNode, int status)
{
    int sum = 0;
    if (status == 0)
    {
        for (int i = 0; i < 5; i++)
        {
            sum += currNode->data->seat[i];
        }
    }
    else if (status == 1)
    {
        for (int i = 0; i < 5; i++)
        {
            sum += currNode->data->remainder[i];
        }
    }
    return sum;
}

flight_Node_p find_flightByflight_id(flight_Node_p headNode, char *flight_id)
{
    flight_Node_p currNode = headNode->next;
    while (currNode != headNode)
    {
        if (strcmp(currNode->data->flight_id, flight_id) == 0)
        {
            return currNode;
        }
        currNode = currNode->next;
    }
    return NULL;
}

void flight_delete(flight_Node_p currNode)
{
    if (currNode == NULL)
        return;

    flight_Node_p prevNode = currNode->prev;
    prevNode->next = currNode->next;
    currNode->next->prev = prevNode;
    free(currNode);
}

int getFlightCount(flight_Node_p headNode)
{
    int count = 0;
    flight_Node_p currNode = headNode->next;
    while (currNode != headNode)
    {
        count++;
        currNode = currNode->next;
    }
    return count;
}

void free_flightList(flight_Node_p headNode)
{
    if (headNode == NULL)
    {
        return;
    }

    flight_Node_p currNode = headNode->next;
    while (currNode != headNode)
    {
        flight_Node_p tempNode = currNode;
        currNode = currNode->next;
        free(tempNode->data);
        free(tempNode);
    }
    free(headNode);
}

flight_Node_p catNode(flight_Node_p newHead, flight_Node_p currNode)
{
    if (currNode == NULL)
        return NULL;

    flight_Node_p newNode = flight_create();
    if (!newNode)
        return NULL;

    newNode->data = malloc(sizeof(flight_t));
    if (!newNode->data)
    {
        free(newNode);
        return NULL;
    }
    memcpy(newNode->data, currNode->data, sizeof(flight_t));

    flight_Node_p TailNode = newHead->prev;
    TailNode->next = newNode;
    newNode->prev = TailNode;
    newNode->next = newHead;
    newHead->prev = newNode;
    return newHead;
}

flight_Node_p find_flightByNo(flight_Node_p headNode)
{
    printf("请输入航班号：");
    char flightNo[20];
    scanf(" %s", flightNo);
    clearChar();
    flight_Node_p currNode = find_flightByflight_id(headNode, flightNo);
    if (currNode == NULL)
    {
        printf("\n没有找到航班号为 [%s] 的航班\n", flightNo);
        waitForAnyKey();
        return NULL;
    }
    return currNode;
}

flight_Node_p find_flightByStart(flight_Node_p headNode)
{
    printf("请输入起始地：");
    char start[20];
    scanf(" %19s", start);
    clearChar();
    flight_Node_p currNode = headNode->next;
    // 查询结果链表
    flight_Node_p resultNode = flight_create();
    while (currNode != headNode)
    {
        if (strcmp(currNode->data->start, start) == 0)
        {
            catNode(resultNode, currNode);
        }
        currNode = currNode->next;
    }
    if (resultNode->next == resultNode)
    {
        printf("\n没有找到起始地为 [%s] 的航班\n", start);
        waitForAnyKey();
        return NULL;
    }
    return resultNode;
}

flight_Node_p find_flightByEnd(flight_Node_p headNode)
{
    printf("请输入目的地：");
    char end[20];
    scanf(" %19s", end);
    clearChar();
    flight_Node_p currNode = headNode->next;
    // 查询结果链表
    flight_Node_p resultNode = flight_create();
    while (currNode != headNode)
    {
        if (strcmp(currNode->data->end, end) == 0)
        {
            catNode(resultNode, currNode);
        }
        currNode = currNode->next;
    }
    if (resultNode->next == resultNode)
    {
        printf("\n没有找到目的地为 [%s] 的航班\n", end);
        waitForAnyKey();
        return NULL;
    }
    return resultNode;
}

flight_Node_p find_flightByDate(flight_Node_p headNode)
{
    printf("请输入日期(yyyy-mm-dd):");
    char date[20];
    scanf(" %19s", date);
    clearChar();
    flight_Node_p currNode = headNode->next;
    // 查询结果链表
    flight_Node_p resultNode = flight_create();
    while (currNode != headNode)
    {
        if (strcmp(currNode->data->date, date) == 0)
        {
            catNode(resultNode, currNode);
        }
        currNode = currNode->next;
    }
    if (resultNode->next == resultNode)
    {
        printf("\n没有找到日期为 [%s] 的航班\n", date);
        waitForAnyKey();
        return NULL;
    }
    return resultNode;
}

int compareTimes(const char *time1, const char *time2)
{
    return strcmp(time1, time2);
}

flight_Node_p find_flightByTime(flight_Node_p headNode)
{
    printf("请输入时间或时间范围(HH:MM 或 HH:MM~HH:MM):");
    char date[20];
    char data2[20];
    scanf(" %19s", date);
    clearChar();
    strcpy(data2, date);
    clearChar();
    flight_Node_p currNode = headNode->next;
    // 查询结果链表
    flight_Node_p resultNode = flight_create();

    char *separator = strchr(date, '~');
    char startTime[6] = {0};
    char endTime[6] = {0};

    if (separator)
    { // 如果存在 ~ 分隔符，说明是范围查询
        *separator = '\0';
        strncpy(startTime, date, 5);
        strncpy(endTime, separator + 1, 5);

        if (compareTimes(startTime, endTime) > 0)
        {
            printf("\n起始时间不能晚于结束时间!\n");
            waitForAnyKey();
            return NULL;
        }

        while (currNode != headNode)
        {
            if (compareTimes(currNode->data->time, startTime) >= 0 && compareTimes(currNode->data->time, endTime) <= 0)
            {
                catNode(resultNode, currNode);
            }
            currNode = currNode->next;
        }
    }
    else
    {
        // 查询指定时间
        while (currNode != headNode)
        {
            if (strcmp(currNode->data->time, date) == 0)
            {
                catNode(resultNode, currNode);
            }
            currNode = currNode->next;
        }
    }
    if (resultNode->next == resultNode)
    {
        printf("\n没有找到时间为 [%s] 的航班\n", data2);
        waitForAnyKey();
        return NULL;
    }
    return resultNode;
}

int isValidPrice(const char *price)
{
    for (int i = 0; price[i] != '\0'; i++)
    {
        if (!isdigit(price[i]))
        {
            return 0;
        }
    }
    return 1;
}

int isPriceInRange(const flight_p flight, int minPrice, int maxPrice)
{
    // 检查每个价格区间
    for (int i = 0; i < 5; i++)
    {
        if (flight->price[i] >= minPrice && flight->price[i] <= maxPrice)
        {
            return 1;
        }
    }
    return 0;
}

int isPriceInRange1(const flight_p flight, int price)
{
    // 检查每个价格区间
    for (int i = 0; i < 5; i++)
    {
        if (flight->price[i] == price)
        {
            return 1;
        }
    }
    return 0;
}

flight_Node_p find_flightByPrice(flight_Node_p headNode)
{
    printf("请输入价格或价格范围(格式:500 或 500~1000):");
    char price[20];
    char price2[20];
    scanf(" %19s", price);
    clearChar();
    flight_Node_p currNode = headNode->next;
    // 查询结果链表
    flight_Node_p resultNode = flight_create();

    char *separator = strchr(price, '~');
    int minPrice = 0, maxPrice = 0;
    strcpy(price2, price);
    if (separator)
    { // 如果存在 ~ 分隔符，说明是范围查询
        *separator = '\0';
        char *minStr = price;
        char *maxStr = separator + 1;

        if (!isValidPrice(minStr) || !isValidPrice(maxStr))
        {
            printf("\n价格必须为数字!\n");
            waitForAnyKey();
            return NULL;
        }

        minPrice = atoi(minStr);
        maxPrice = atoi(maxStr);

        if (minPrice > maxPrice)
        {
            printf("\n最低价格不能高于最高价格!\n");
            waitForAnyKey();
            return NULL;
        }

        while (currNode != headNode)
        {
            if (isPriceInRange(currNode->data, minPrice, maxPrice))
            {
                catNode(resultNode, currNode);
            }
            currNode = currNode->next;
        }
    }
    else
    {
        int price1 = atoi(price);

        if (!isValidPrice(price))
        {
            printf("\n价格必须为数字!\n");
            waitForAnyKey();
            return NULL;
        }
        while (currNode != headNode)
        {
            if (isPriceInRange1(currNode->data, price1))
            {
                catNode(resultNode, currNode);
            }
            currNode = currNode->next;
        }
    }

    if (resultNode->next == resultNode)
    {
        printf("\n没有找到价格为 [%s] 的航班\n", price2);
        waitForAnyKey();
        return NULL;
    }
    return resultNode;
}

void updata_flight_id(flight_Node_p currNode)
{
    char newFlight_id[20];
    printf("旧航班号为%s\n", currNode->data->flight_id);
    printf("请输入新航班号: ");
    while (1)
    {
        scanf(" %6s", newFlight_id);
        clearChar();
        int status = validate_string_format(newFlight_id);
        if (status == 1)
        {
            break;
        }
        else
        {
            printf("输入格式错误,航班号格式为前两位大写字母,后四位数字!\n请重新输入:");
        }
    }
    if (strcmp(currNode->data->flight_id, newFlight_id) != 0)
    {
        if (find_flight_id(airline_headNode, newFlight_id) == 1)
        {
            printf("该航班号已存在!\n");
            return;
        }
    }
    if (strcmp(newFlight_id, currNode->data->flight_id) != 0)
    {
        printf("确认修改航班号?(Y/N)");
        if (if_goOn() == 1)
        {
            updata_my_flightByflight_id(myflight_headNode, currNode->data->flight_id, newFlight_id); // 修改用户航班号
            strcpy(find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->flight_id, newFlight_id);
            strcpy(currNode->data->flight_id, newFlight_id);
            printf("已修改航班号!\n");
        }
        else
        {
            printf("已取消修改航班号!\n");
        }
    }
    else
    {
        printf("请不要输入相同的航班号!\n");
    }
}

void updata_start(flight_Node_p currNode)
{
    char newStart[20];
    printf("旧出发地为%s\n", currNode->data->start);
    printf("请输入新出发地: ");
    scanf(" %19s", newStart);
    clearChar();
    printf("确认修改出发地?(Y/N)");
    if (if_goOn() == 1)
    {
        strcpy(currNode->data->start, newStart);
        strcpy(find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->start, newStart);
        printf("已修改出发地!\n");
    }
    else
    {
        printf("已取消修改!\n");
    }
}

void updata_end(flight_Node_p currNode)
{
    char newEnd[20];
    printf("旧目的地为%s\n", currNode->data->end);
    printf("请输入新目的地: ");
    scanf(" %19s", newEnd);
    clearChar();
    printf("确认修改目的地?(Y/N)");
    if (if_goOn() == 1)
    {
        strcpy(currNode->data->end, newEnd);
        strcpy(find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->end, newEnd);
        printf("已修改目的地!\n");
    }
    else
    {
        printf("已取消修改!\n");
    }
}

void updata_date(flight_Node_p currNode)
{
    while (1)
    {
        char newDate[11];
        printf("旧日期为%s\n", currNode->data->date);
        printf("请输入新日期(YYYY-MM-DD): ");
        scanf(" %10s", newDate);
        clearChar();
        if (!isValidDate(newDate))
        {
            printf("日期格式错误!请按YYYY-MM-DD格式输入有效日期\n");
            continue;
        }
        printf("确认修改日期?(Y/N)");
        if (if_goOn() == 1)
        {
            strcpy(currNode->data->date, newDate);
            strcpy(find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->date, newDate);
            printf("已修改日期!\n");
            break;
        }
        else
        {
            printf("已取消修改!\n");
            break;
        }
    }
}

void updata_time(flight_Node_p currNode)
{
    while (1)
    {
        char newTime[6];
        printf("旧时间为%s\n", currNode->data->time);
        printf("请输入新时间(HH:MM): ");
        scanf(" %5s", newTime);
        clearChar();
        if (!isValidTime(newTime))
        {
            printf("时间格式错误!请按HH:MM格式输入有效时间\n");
            continue;
        }
        printf("确认修改时间?(Y/N)");
        if (if_goOn() == 1)
        {
            strcpy(currNode->data->time, newTime);
            strcpy(find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->time, newTime);
            printf("已修改时间!\n");
            break;
        }
        else
        {
            printf("已取消修改!\n");
            break;
        }
    }
}

void updata_price(flight_Node_p currNode)
{
    int seat_type;
    int newprice;
    printf("请输入需要修改的舱位类型: [0] 商务舱 [1] 一等舱 [2] 经济舱 [3] 头等舱 [4]公务舱");
    scanf(" %d", &seat_type);
    clearChar();
    if (seat_type > 4 || seat_type < 0)
    {
        printf("输入错误!\n");
        return;
    }
    printf("旧票价为:%d\n", currNode->data->price[seat_type]);
    printf("请输入新票价: ");
    scanf(" %d", &newprice);
    clearChar();
    printf("确认修改票价?(Y/N)");
    if (if_goOn() == 1)
    {
        currNode->data->price[seat_type] = newprice;
        find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->price[seat_type] = newprice;
        printf("已修改票价!\n");
    }
    else
    {
        printf("已取消修改!\n");
    }
}

void updata_seat(flight_Node_p currNode)
{
    int newseat, seat_type;
    printf("请输入需要修改的舱位类型: [0] 商务舱 [1] 一等舱 [2] 经济舱 [3] 头等舱 [4]公务舱");
    scanf(" %d", &seat_type);
    clearChar();
    if (seat_type > 4 || seat_type < 0)
    {
        printf("输入错误!\n");
        return;
    }
    printf("旧座位数为:%d\n", currNode->data->seat[seat_type]);
    printf("请输入新座位数: ");
    scanf(" %d", &newseat);
    clearChar();
    printf("确认修改座位数?(Y/N)");
    if (if_goOn() == 1)
    {
        if (newseat < currNode->data->seat[seat_type])
        {
            int sold_seats = currNode->data->seat[seat_type] - currNode->data->remainder[seat_type]; // 当前已售座位数
            int need_refund = sold_seats - newseat;

            if (need_refund > 0)
            {
                printf("舱位 %s:当前已售%d张,新座位数%d,需退票%d张\n", flight_index_to_type(seat_type), sold_seats, newseat, need_refund);
                printf("确认退票?(Y/N)");

                if (if_goOn() == 1)
                {
                    // 执行退票操作
                    for (int j = 0; j < need_refund; j++)
                    {
                        find_my_flight_by_seat(myflight_headNode, currNode->data->flight_id, seat_type);
                    }
                    // 更新座位数
                    find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->seat[seat_type] = newseat;
                    find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->remainder[seat_type] = newseat;
                    currNode->data->seat[seat_type] = newseat;
                    currNode->data->remainder[seat_type] = newseat;

                    printf("修改成功\n");
                }
                else
                {
                    printf("已取消修改座位数\n");
                }
            }
            else
            {
                // 无需退票，直接更新
                find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->seat[seat_type] = newseat;
                find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->remainder[seat_type] = newseat - sold_seats;
                currNode->data->remainder[seat_type] = newseat - sold_seats;
                currNode->data->seat[seat_type] = newseat;
                printf("修改成功\n");
            }
        }

        else if (newseat > currNode->data->seat[seat_type])
        {
            // 增加座位数的情况
            find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->remainder[seat_type] += newseat - currNode->data->seat[seat_type];
            find_flightByflight_id(flight_headNode, currNode->data->flight_id)->data->seat[seat_type] = newseat;
            currNode->data->remainder[seat_type] += newseat - currNode->data->seat[seat_type];
            currNode->data->seat[seat_type] = newseat;
        }
    }
    else
    {
        printf("已取消修改!\n");
    }
}

// 查找航班号是否重复
int find_flight_id(flight_Node_p headNode, char *flight_id)
{
    flight_Node_p currNode = headNode->next;
    while (currNode != headNode)
    {
        if (strcmp(currNode->data->flight_id, flight_id) == 0)
        {
            return 1;
        }
        currNode = currNode->next;
    }
    return 0;
}

flight_Node_p find_flight_ListBystatus(flight_Node_p headNode)
{
    flight_Node_p newHead = flight_create();
    flight_Node_p currNode = headNode->next;

    while (currNode != headNode)
    {
        if (currNode->data->status == 0)
        {
            flight_p data = (flight_p)malloc(sizeof(flight_t));
            memcpy(data, currNode->data, sizeof(flight_t));
            flight_insert_tail(newHead, data);
        }
        currNode = currNode->next;
    }
    return newHead;
}